package org.springblade.modules.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.cache.DictCache;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.TenantIgnore;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.BuildingUserContractDTO;
import org.springblade.modules.admin.dto.MaintainTimeSubmitDTO;
import org.springblade.modules.admin.dto.PlanCheckStatisticsQueryDTO;
import org.springblade.modules.admin.dto.ProjectDTO;
import org.springblade.modules.admin.dto.TlwBuildingElevatorQuery;
import org.springblade.modules.admin.dto.building.BuildingUserElevatorDTO;
import org.springblade.modules.admin.dto.platform.BuildingSearchDTO;
import org.springblade.modules.admin.dto.sugar.SugarSearchDTO;
import org.springblade.modules.admin.dto.sugar.rescue.SugarRescueSearchDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.entity.es.ProjectDocument;
import org.springblade.modules.admin.enums.*;
import org.springblade.modules.admin.mapper.BuildingMapper;
import org.springblade.modules.admin.mapper.es.ProjectDocumentMapper;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.service.erp.IPartnerCloudBuildingService;
import org.springblade.modules.admin.utils.TranslationUtil;
import org.springblade.modules.admin.vo.*;
import org.springblade.modules.admin.vo.building.BuildingUserElevatorDetailVo;
import org.springblade.modules.admin.vo.building.BuildingUserElevatorVo;
import org.springblade.modules.admin.vo.building.BuildingUserStatusVo;
import org.springblade.modules.admin.vo.erp.service.BuildingMessageVO;
import org.springblade.modules.admin.vo.feishu.GalaxyMaintainCustomerVO;
import org.springblade.modules.admin.vo.openapi.SidaBuildingBasicVO;
import org.springblade.modules.admin.vo.openapi.SidaBuildingMaintainTimeVO;
import org.springblade.modules.admin.vo.platform.BuildingSumVo;
import org.springblade.modules.admin.vo.platform.BuildingVo;
import org.springblade.modules.admin.vo.rescue.map.MapRescueBuildingDetailVO;
import org.springblade.modules.admin.vo.sugar.BuildingStatisticsListVO;
import org.springblade.modules.admin.vo.sugar.ChartItemVO;
import org.springblade.modules.admin.vo.sugar.PieChartVO;
import org.springblade.modules.admin.vo.sugar.ProjectOverviewVO;
import org.springblade.modules.admin.vo.sugar.bi.BILarkGroupSourceVO;
import org.springblade.modules.admin.vo.sugar.bi.BILarkRescueAreaResourceVO;
import org.springblade.modules.admin.vo.sugar.bi.BILarkRescueBigTableVO;
import org.springblade.modules.admin.vo.sugar.bi.BILarkRescueBuildingSourceVO;
import org.springblade.modules.admin.vo.sugar.map.SugarMapEleBuildVo;
import org.springblade.modules.admin.vo.sugar.rescue.SugarRescueListVO;
import org.springblade.modules.admin.vo.tlw.TlwBuildingVO;
import org.springblade.modules.admin.vo.tlw.TlwElevatorEstateUserVO;
import org.springblade.modules.admin.vo.tlw.TlwElevatorVO;
import org.springblade.modules.system.entity.Dept;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.entity.Tenant;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IDeptService;
import org.springblade.modules.system.service.ITenantService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 楼盘信息 服务实现类
 *
 * @author BladeX
 * @since 2021-05-11
 */
@Service
@Slf4j
@AllArgsConstructor
public class BuildingServiceImpl extends BaseServiceImpl<BuildingMapper, Building> implements BuildingService {

	private final IBuildingContactsService buildingContactsService;

	private final BladeRedis bladeRedis;

	private final ITenantService tenantService;

	private final IUserService userService;

	private final BuildingElevatorTemplateService buildingElevatorTemplateService;

	private final IBuildingExtService buildingExtService;

	private final IBuildingMaintainTimeService buildingMaintainTimeService;

	private final ElevatorService elevatorService;

	private final RelationAliasService relationAliasService;

	private final IPartnerCloudBuildingService erpBuildingService;

	private final ProjectDocumentMapper projectDocumentMapper;
	private final IDeptService deptService;
	private final ElevatorPrincipalDeptService elevatorPrincipalDeptService;

	private final IBuildingUserContractService buildingUserContractService;

	@Override
	public IPage<BuildingVO> selectBuildingPage(IPage<BuildingVO> page, Building building) {

		building.setTenantId(AuthUtil.getTenantId());
		return page.setRecords(baseMapper.selectBuildingPage(page, building));
	}

	@Override
	public BuildingVO selectBuilding(Long id) {
		BuildingVO buildingVO = baseMapper.selectBuilding(id);
		return buildingVO;
	}

	@Override
	public List<BuildingVO> selectBuildingByIds(List<Long> ids) {
		return baseMapper.selectBuildingByIds(ids);
	}

	@Override
	public List<BuildingVO> buildingVOList() {

		return baseMapper.buildingVOList(AuthUtil.getTenantId());
	}

	@Override
	public List<EstateUserInfoVO> selectEstateUserInfoByBuildingId(Long buildingId) {
		return baseMapper.selectEstateUserInfoByBuildingId(buildingId);
	}

	@Override
	public IPage<ProjectVO> selectProjectPage(IPage<ProjectVO> page, Building building) {
		// 2023-10-25 新增项目别名
		List<ProjectVO> list = baseMapper.selectProjectPage(page.getSize() == 0 ? null : page, building);
		List<Dict> dictList = DictCache.getList(PROJECT_TYPE_CODE);
		Map<String, String> dictMap = dictList.stream().collect(Collectors.toMap(Dict::getDictKey, Dict::getDictValue));
		for (int i = 0; i < list.size(); i++) {
			list.get(i).setTypeName(dictMap.get(list.get(i).getType()));
			List<BuildingElevatorTemplateVO> templates = list.get(i).getTemplates();
			if (ObjectUtil.isNotEmpty(templates)) {
				templates.forEach(e -> {
					List<String> names = Func.toStrList("/", e.getName());
					e.setTemplates(names.stream().map(k -> {
						BuildingElevatorTemplateVO templateVO = new BuildingElevatorTemplateVO();
						templateVO.setName(k);
						return templateVO;
					}).collect(Collectors.toList()));
				});
			}
		}
		return page.setRecords(list);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Long projectSaveOrEdit(ProjectDTO project) {
		if (checkProject(project.getId(), project.getName(), project.getLongitude(), project.getLatitude())) {
			throw new ServiceException("项目已存在，不能进行操作！");
		}
		// 若涉及缓存的关键信息未修改，则不执行缓存更新
		boolean ifFlush = true;
		if (!Func.isNull(project.getId())) {
			Building updateBuilding = this.selectById(project.getId());
			boolean temp1 = true;
			boolean temp2 = true;
			boolean temp3 = true;
			if (!Func.isNull(project.getName())) {
				temp1 = !updateBuilding.getName().equals(project.getName());
			}
			if (!Func.isNull(project.getLatitude())) {
				temp2 = !updateBuilding.getLatitude().equals(project.getLatitude());
			}
			if (!Func.isNull(project.getLongitude())) {
				temp3 = !updateBuilding.getLongitude().equals(project.getLongitude());
			}
			ifFlush = temp1 || temp2 || temp3;
		}
		Building building = new Building();
		building.setSourceTenantId(AuthUtil.getTenantId());
		Tenant tenant = tenantService.getByTenantId(AuthUtil.getTenantId());
		building.setSourceTenantName(tenant.getTenantName());
		building.setSourceType(tenant.getCompanyCategory());
		building.setSourceUserName(userService.getById(AuthUtil.getUserId()).getRealName());
		BeanUtils.copyProperties(project, building);

		if (StrUtil.isNotEmpty(building.getName())) {
			final String firstLetter = PinyinUtil.getFirstLetter(building.getName(), "");
			building.setZhCode(firstLetter);
		}
		boolean res = this.saveOrUpdate(building);
		// 项目扩展信息
		addBuildingExt(building.getId(), project.getBuildingExt());

		if (ifFlush) {
			// 用于人员轨迹的缓存
			log.info("项目更新，开始同步缓存");
			long beginCache = System.currentTimeMillis();
			addRedisBuilding();
			long endCache = System.currentTimeMillis();
			log.info("缓存操作结束，全表缓存更新耗时{}ms", endCache - beginCache);
		}

		// 新增项目别名
		addRelationAliases(project.getRelationAliases(), building);

		if (res) {
			Long buildingId = building.getId();
			// 2025-01-08 新增异步同步到erp逻辑
			erpBuildingService.syncErpBuilding(buildingId);
			//新增或修改模板信息
			List<BuildingElevatorTemplate> templates = project.getTemplates();
			if (ObjectUtil.isNotEmpty(templates)) {
				// 判断重复
				List<String> checkTemplateList = templates.stream().map(t -> String.format("%d-%s", t.getLevel(), t.getName())).distinct().collect(Collectors.toList());
				if (checkTemplateList.size() != templates.size()) {
					throw new ServiceException("请勿重复设置相同的电梯命名结构！");
				}

				//buildingId 存入列表 , 模板信息列表存入模板
				for (BuildingElevatorTemplate template : templates) {
					template.setBuildingId(buildingId);
					BuildingElevatorTemplate buildingElevatorTemplate = buildingElevatorTemplateService.getOne(Wrappers.<BuildingElevatorTemplate>lambdaQuery().eq(BuildingElevatorTemplate::getBuildingId, buildingId).eq(BuildingElevatorTemplate::getName, template.getName()));
					if (ObjectUtil.isNotEmpty(buildingElevatorTemplate)) {
						template.setId(buildingElevatorTemplate.getId());
					}
				}
				buildingElevatorTemplateService.saveOrUpdateBatch(templates);
				//删除模板信息
				List<Long> betIds = templates.stream().map(BuildingElevatorTemplate::getId).collect(Collectors.toList());
				buildingElevatorTemplateService.remove(new LambdaQueryWrapper<BuildingElevatorTemplate>().eq(BuildingElevatorTemplate::getBuildingId, buildingId).notIn(BuildingElevatorTemplate::getId, betIds));
			} else {
				//删除模板信息
				buildingElevatorTemplateService.remove(new LambdaQueryWrapper<BuildingElevatorTemplate>().eq(BuildingElevatorTemplate::getBuildingId, buildingId));
			}

			//小区联系人
			BuildingContacts buildingContacts = buildingContactsService.getOne(Wrappers.<BuildingContacts>lambdaQuery().eq(BuildingContacts::getBuildingId, building.getId()).eq(BuildingContacts::getIsDeleted, 0), false);
			if (buildingContacts == null) {
				buildingContacts = new BuildingContacts();
				buildingContacts.setBuildingId(building.getId());
			}
			buildingContacts.setContactsName(project.getContactsName());
			buildingContacts.setPhone(project.getPhone());
			buildingContacts.setGender(project.getGender());

			buildingContactsService.saveOrUpdate(buildingContacts);

			return buildingId;
		}
		log.info("其它业务开始缓存刷新");
		long otherCache = System.currentTimeMillis();
		addCacheable();
		long otherCacheEnd = System.currentTimeMillis();
		log.info("其它业务缓存刷新结束，用时{}ms", otherCacheEnd - otherCache);

		return building.getId();
	}

	public boolean addRelationAliases(List<RelationAlias> relationAliases, Building building) {
		long begin = System.currentTimeMillis();
		log.info("开始插入别名");
		List<RelationAlias> existList = relationAliasService.list(new LambdaQueryWrapper<RelationAlias>().eq(RelationAlias::getRelationId, building.getId()).eq(BaseEntity::getIsDeleted, 0));
		if (Func.isNotEmpty(existList)) {
			relationAliasService.removeByHand(building.getId());
		}
		// 同步 es 逻辑
		ProjectDocument projectDocument = new ProjectDocument();
		projectDocument.setId(building.getId());
		projectDocument.setName(building.getName());
		projectDocument.setNamePinyin(building.getName());
		projectDocument.setProvinceCode(building.getProvinceCode());
		projectDocument.setCityCode(building.getCityCode());
		projectDocument.setAdCode(building.getAdCode());
		if (Func.isEmpty(building.getTenantId())) {
			projectDocument.setTenantId(AuthUtil.getTenantId());
		} else {
			projectDocument.setTenantId(building.getTenantId());
		}

		if (Func.isNotEmpty(relationAliases)) {
			for (RelationAlias alias : relationAliases) {
				alias.setId(null);
				alias.setStatus(RelationAliasTypeEnum.BUILDING.getType());
				alias.setRelationId(building.getId());
			}
			// 同步 es 逻辑，复用通用document类更新 es
			String esAliases = relationAliases.stream().map(RelationAlias::getAlias).collect(Collectors.joining(","));
			projectDocument.setAlias(esAliases);
			projectDocument.setAliasPinyin(esAliases);
			Integer insert = projectDocumentMapper.insert(projectDocument);
			log.info("es 更新条数{}", insert);
			long end = System.currentTimeMillis();
			log.info("别名插入结束，插入别名时长{}ms", end - begin);
			return relationAliasService.saveOrUpdateBatch(relationAliases);
		} else {
			// 删除 对应别名
			projectDocument.setAlias(null);
			projectDocument.setAliasPinyin(null);
			Integer insert = projectDocumentMapper.insert(projectDocument);
			log.info("es 更新条数{}", insert);
			long end = System.currentTimeMillis();
			log.info("别名更新结束，时长{}ms", end - begin);
			return Boolean.TRUE;
		}

	}


	/**
	 * @Author lsay
	 * @Description {
	 * 项目扩展信息
	 * @Date 10:09 2023/8/30
	 * @Param
	 **/
	private void addBuildingExt(Long buildingId, BuildingExt buildingExt) {
		buildingExt = ObjectUtil.isNotEmpty(buildingExt) ? buildingExt : new BuildingExt();
		buildingExt.setBuildingId(buildingId);
		BuildingExt ext = buildingExtService.getOne(Wrappers.<BuildingExt>lambdaQuery().eq(BuildingExt::getBuildingId, buildingId));
		if (ObjectUtil.isNotEmpty(ext)) {
			buildingExt.setId(ext.getId());
		}
		buildingExtService.saveOrUpdate(buildingExt);
		if (!buildingExt.getAllowMaintain().equals(0)) {
			buildingMaintainTimeService.submit(buildingId, buildingExt.getBuildingMaintainTimes());
		}
	}

	/**
	 * 人员轨迹缓存
	 */
	@Override
	public void addRedisBuilding() {
		// 组合 key ： 前缀 + 租户id
		String prefix = BuildingCacheEnum.BUILDING_REDIS_LIST.getKey();
		String tenantId = AuthUtil.getTenantId();
		String key = prefix + tenantId;
		// 获取目标对象列表
		List<BuildingRedisVO> buildingList = listForVO();
		bladeRedis.del(key);
		Long aLong = bladeRedis.lLen(key);
		log.info("旧缓存是否删除成功{}", aLong == 0);
		log.info("{}", key);
		// 执行
		buildingList.forEach(b -> bladeRedis.lPush(key, JSON.toJSONString(b)));
		Object[] redisBuildings = bladeRedis.lRange(key, 0, -1).toArray();
		log.info("{}", redisBuildings.toString());
	}


	@Override
	public BuildingExt selectBuildingExtDetail(Long buildingId) {
		BuildingExt buildingExt = buildingExtService.getOne(Wrappers.<BuildingExt>lambdaQuery().eq(BuildingExt::getBuildingId, buildingId));
		final Building building = this.getById(buildingId);
		BuildingContacts buildingContacts = buildingContactsService.getOne(Wrappers.<BuildingContacts>lambdaQuery().eq(BuildingContacts::getBuildingId, buildingId));
		if (buildingContacts != null) {
			building.setUnitName(buildingContacts.getContactsName());
			building.setPhone(buildingContacts.getPhone());
		}
		if (building.getBusinessUserId() != null) {
			User user = userService.getById(building.getBusinessUserId());
			if (user != null) {
				building.setBusinessUserName(user.getRealName());
			}
		}
		buildingExt.setBuilding(building);

		List<MaintainTimeSubmitDTO> buildingMaintainTimes = buildingMaintainTimeService.selectMaintainTimes(buildingId);
		buildingExt.setBuildingMaintainTimes(buildingMaintainTimes);

		// 2023-10-24 新增项目别名
		List<RelationAlias> relationAliases = relationAliasService.list(new LambdaQueryWrapper<RelationAlias>().eq(RelationAlias::getRelationId, buildingId).eq(BaseEntity::getIsDeleted, 0));
		buildingExt.setRelationAliases(relationAliases);
		List<BuildingElevatorTemplateVO> templates = baseMapper.selectBuildingElevatorTemplateByBuilding(buildingId);
		if (templates.size() > 0) {
			templates.forEach(e -> {
				List<String> names = Func.toStrList("/", e.getName());
				e.setTemplates(names.stream().map(k -> {
					BuildingElevatorTemplateVO templateVO = new BuildingElevatorTemplateVO();
					templateVO.setName(k);
					return templateVO;
				}).collect(Collectors.toList()));
			});
		}
		buildingExt.setTemplates(templates);
		return buildingExt;
	}

	@Override
	public MapRescueBuildingDetailVO selectMapRescueBuildingDetail(Long buildingId) {
		MapRescueBuildingDetailVO detailVO = baseMapper.selectMapRescueBuildingDetail(buildingId);
		if (Func.isEmpty(detailVO)) {
			return null;
		}
		BuildingExt buildingExt = buildingExtService.getOne(Wrappers.<BuildingExt>lambdaQuery().eq(BuildingExt::getBuildingId, buildingId));
		List<MaintainTimeSubmitDTO> buildingMaintainTimes = buildingMaintainTimeService.selectMaintainTimes(buildingId);
		buildingExt.setBuildingMaintainTimes(buildingMaintainTimes);
		detailVO.setBuildingExt(buildingExt);
		return detailVO;
	}


	private void addCacheable() {
		String key = "buildingList";
		bladeRedis.del(key + AuthUtil.getTenantId());
		List<Building> list = this.list();
		List<BuildingSignVo> resultList = new ArrayList<>();
		for (Building building : list) {
			BuildingSignVo buildingSignVo = new BuildingSignVo();
			BeanUtil.copyProperties(building, buildingSignVo);
			resultList.add(buildingSignVo);
		}
		bladeRedis.set(key + AuthUtil.getTenantId(), JSON.toJSONString(resultList));
	}


	/**
	 * 小区项目校验
	 */
	private boolean checkProject(Long id, String name, BigDecimal longitude, BigDecimal latitude) {
		long isExist = baseMapper.selectList(Wrappers.<Building>lambdaQuery().eq(Building::getName, name).eq(Building::getLongitude, longitude).eq(Building::getLatitude, latitude)).stream().filter(building -> !building.getId().equals(id)).count();
		return isExist > 0;
	}

	@Override
	public List<String> getALlCityNameList() {
		List<String> cityList = list(Wrappers.<Building>query().select("DISTINCT city_name")).stream().map(t -> t.getCityName()).collect(Collectors.toList());
		return cityList;
	}

	@Override
	public List<String> getALlAdNameList(String cityName) {
		List<String> adList = list(Wrappers.<Building>lambdaQuery().select(Building::getAdName).eq(Building::getCityName, cityName).eq(Building::getIsDeleted, 0)).stream().map(building -> building.getAdName()).distinct().collect(Collectors.toList());
		return adList;
	}

	@Override
	public List<User> getUserListById(Long id) {


		return baseMapper.getUserListById(id);
	}

	@Override
	public List<Building> getList(SugarSearchDTO sugarSearchDTO) {
		List<Dept> deptList = deptService.selectDeptAndAllChildDepts(sugarSearchDTO.getDeptIds());
		List<Long> deptIds = deptList.stream().map(Dept::getId).collect(Collectors.toList());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId, deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).collect(Collectors.toList());
		if (Func.isNotEmpty(elevatorIds)) {
			sugarSearchDTO.setElevatorIds(elevatorIds);
			return baseMapper.getList(sugarSearchDTO);
		} else {
			return new ArrayList<>();
		}
	}

	@Override
	public List<BuildingTreeVo> treeList() {
		List<BuildingTreeVo> buildingTreeVos = baseMapper.treeList();
		if (CollectionUtils.isEmpty(buildingTreeVos)) {
			return null;
		}
		Map<Long, List<BuildingTreeVo>> collect = buildingTreeVos.stream().collect(Collectors.groupingBy(BuildingTreeVo::getParentId));
		List<BuildingTreeVo> buildingTreeVos1 = collect.get(0L);
		for (BuildingTreeVo buildingTreeVo : buildingTreeVos1) {
			getChildTree(buildingTreeVo, collect);
		}
		return buildingTreeVos1;
	}

	@Override
	public IPage<BuildingVo> selectBuildingPageV2(IPage<BuildingVo> page, BuildingSearchDTO building) {

		return baseMapper.selectBuildingPageV2(page, building);
	}

	@Override
	public BuildingSumVo getBuildingSumInfo() {
		return baseMapper.getBuildingSumInfo();
	}

	private void getChildTree(BuildingTreeVo buildingTreeVo, Map<Long, List<BuildingTreeVo>> collect) {
		List<BuildingTreeVo> buildingTreeVos = collect.get(buildingTreeVo.getId());
		if (buildingTreeVos != null && buildingTreeVos.size() > 0) {
			buildingTreeVo.setChildren(buildingTreeVos);
			buildingTreeVo.setHasChildren(true);
			for (int i = 0; i < buildingTreeVos.size(); i++) {
				getChildTree(buildingTreeVos.get(0), collect);
			}
		}
	}

	@Override
	public BuildingSelectListStatisticsVO buildingSelectList() {
		List<BuildingSelectListVO> list = baseMapper.buildingSelectList();
		long buildingTotal = list.stream().count();
		long elevatorTotal = list.stream().collect(Collectors.summingLong(t -> t.getTotal()));

		BuildingSelectListStatisticsVO listStatistics = new BuildingSelectListStatisticsVO();
		listStatistics.setList(list);
		listStatistics.setBuildingTotal(buildingTotal);
		listStatistics.setElevatorTotal(elevatorTotal);
		return listStatistics;
	}

	@Override
	public List<BuildingSelectListVO> buildingTlwSelectList(PlanConfigSearchVO search) {
		return baseMapper.buildingTlwSelectList(search);
	}

	@Override
	public PieChartVO comingExpiryProject() {
		return projectStatisticsDataHandle(3);
	}

	@Override
	public PieChartVO projectElevator(PlanCheckStatisticsQueryDTO queryDTO) {
		PieChartVO pieChartVO = new PieChartVO();
		List<Dept> deptList = deptService.selectDeptAndAllChildDepts(queryDTO.getDeptIds());
		List<Long> deptIds = deptList.stream().map(Dept::getId).collect(Collectors.toList());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.listInMaintainElevatorByDeptIds(deptIds);
		List<ChartItemVO> list = new ArrayList<>();
		if (Func.isNotEmpty(queryDTO.getDeptIds())) {
			queryDTO.getDeptIds().forEach(e -> {
				ChartItemVO itemVO = new ChartItemVO();
				Dept dept = deptList.stream().filter(d -> d.getId().equals(e)).findFirst().orElse(null);
				itemVO.setId(dept.getId());
				itemVO.setName(dept.getDeptName());
				List<Long> deptChildIds = deptList.stream().filter(d -> d.getAncestors().contains(String.valueOf(e))).map(Dept::getId).collect(Collectors.toList());
				itemVO.setEleTotal(elevatorDepts.stream().filter(d -> d.getDeptId().equals(e) || (Func.isNotEmpty(deptChildIds) && deptChildIds.contains(d))).map(ElevatorPrincipalDept::getElevatorId).distinct().count());
				itemVO.setPercentage(BigDecimal.ZERO);
				list.add(itemVO);
			});
		} else {
			deptIds.forEach(e -> {
				ChartItemVO itemVO = new ChartItemVO();
				Dept dept = deptList.stream().filter(d -> d.getId().equals(e)).findFirst().orElse(null);
				itemVO.setId(dept.getId());
				itemVO.setName(dept.getDeptName());
				List<Long> deptChildIds = deptList.stream().filter(d -> d.getAncestors().contains(String.valueOf(e))).map(Dept::getId).collect(Collectors.toList());
				itemVO.setEleTotal(elevatorDepts.stream().filter(d -> d.getDeptId().equals(e) || (Func.isNotEmpty(deptChildIds) && deptChildIds.contains(d))).map(ElevatorPrincipalDept::getElevatorId).distinct().count());
				itemVO.setPercentage(BigDecimal.ZERO);
				list.add(itemVO);
			});
		}
//		List<ChartItemVO> list = baseMapper.selectPlanElevatorStatistics(AuthUtil.getTenantId());
		pieChartVO.setValue1(list.stream().count());
		// 电梯总数
		long sumEleTotal = list.stream().collect(Collectors.summingLong(t -> t.getEleTotal()));
		list.stream().forEach(item -> {

			String nameI18nResult = TranslationUtil.translateToEnglish(item.getName());
			item.setNameI18n(nameI18nResult);
		});
		pieChartVO.setValue2(sumEleTotal);
		if (sumEleTotal > 0) {
			list.forEach(item -> {
				item.setPercentage(NumberUtil.div(String.valueOf(item.getEleTotal()), String.valueOf(sumEleTotal), 3));
			});
		}
		pieChartVO.setItems(list);
		return pieChartVO;
	}

	/**
	 * 项目统计数据封装
	 *
	 * @param condition 合同扩展状态(对应blade_building_contract_plus表contract_ext_status)
	 *                  1:待续签
	 *                  2:已续签
	 *                  3:即将到期
	 *                  4:已脱保
	 *                  5:已作废
	 * @return
	 */
	private PieChartVO projectStatisticsDataHandle(Integer condition) {
		PieChartVO pieChartVO = new PieChartVO();
		List<BuildingStatisticsListVO> statisticsList = baseMapper.buildingStatisticsList(condition);
		pieChartVO.setValue1(statisticsList.stream().count());
		long eleTotal = statisticsList.stream().mapToLong(BuildingStatisticsListVO::getEleTotal).sum();
		pieChartVO.setValue2(eleTotal);

		List<ChartItemVO> items = new ArrayList<>();
		List<BuildingStatisticsListVO> top5List = statisticsList.stream().sorted(Comparator.comparing(BuildingStatisticsListVO::getEleTotal).reversed()).limit(4).collect(Collectors.toList());
		for (BuildingStatisticsListVO top : top5List) {
			ChartItemVO item = new ChartItemVO();
			item.setId(top.getBuildingId());
			item.setName(top.getBuildingName());
			item.setPercentage(NumberUtil.div(String.valueOf(top.getEleTotal()), String.valueOf(eleTotal), 3));
			item.setEleTotal(top.getEleTotal());
			items.add(item);
		}

		// ”其它“ 统计
		long top5EleTotal = top5List.stream().mapToLong(BuildingStatisticsListVO::getEleTotal).sum();
		if (top5EleTotal != eleTotal) {
			ChartItemVO item = new ChartItemVO();
			item.setName("其它");
			long otherEle = eleTotal - top5EleTotal;
			item.setEleTotal(otherEle);
			item.setPercentage(NumberUtil.div(String.valueOf(otherEle), String.valueOf(eleTotal), 3));
			items.add(item);
		}
		pieChartVO.setItems(items);
		return pieChartVO;
	}

	@Override
	public ProjectOverviewVO projectOverview() {
		ProjectOverviewVO projectOverviewVO = new ProjectOverviewVO();
		List<BuildingContractPlusVO> contractList = baseMapper.selectBuildingContractList();
		// 已生效项目
		long workedProjectTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractStatus(), ContractStatusEnum.WORKED.getStatus())).map(t -> t.getBuildingId()).distinct().count();
		projectOverviewVO.setWorkedProjectTotal(workedProjectTotal);

		// 已生效电梯
		long workedElevatorTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractStatus(), ContractStatusEnum.WORKED.getStatus())).map(t -> t.getElevatorId()).distinct().count();
		projectOverviewVO.setWorkedElevatorTotal(workedElevatorTotal);

		// 即将到期项目
		long comingExpiryProjectTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractExtStatus(), 3)).map(t -> t.getBuildingId()).distinct().count();
		projectOverviewVO.setComingExpiryProjectTotal(comingExpiryProjectTotal);

		// 即将到期电梯
		long comingExpiryElevatorTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractExtStatus(), 3)).map(t -> t.getElevatorId()).distinct().count();
		projectOverviewVO.setComingExpiryElevatorTotal(comingExpiryElevatorTotal);

		// 本月新签项目
		long curMonthNewProjectTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractSource(), 1) && DateUtil.isSameMonth(t.getCreateTime(), DateUtil.date()) && t.getContractExtStatus() != 5 && t.getStatus() == 2).map(t -> t.getBuildingId()).distinct().count();
		projectOverviewVO.setCurMonthNewProjectTotal(curMonthNewProjectTotal);

		// 本月新签电梯
		long curMonthNewElevatorTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractSource(), 1) && DateUtil.isSameMonth(t.getCreateTime(), DateUtil.date()) && t.getContractExtStatus() != 5 && t.getStatus() == 2).map(t -> t.getElevatorId()).distinct().count();
		projectOverviewVO.setCurMonthNewElevatorTotal(curMonthNewElevatorTotal);

		// 本月续签项目
		long curMonthRenewalProjectTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractSource(), 2) && DateUtil.isSameMonth(t.getCreateTime(), DateUtil.date()) && t.getContractExtStatus() != 5 && t.getStatus() == 2).map(t -> t.getBuildingId()).distinct().count();
		projectOverviewVO.setCurMonthRenewalProjectTotal(curMonthRenewalProjectTotal);

		// 本月续签电梯
		long curMonthRenewalElevatorTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractSource(), 2) && DateUtil.isSameMonth(t.getCreateTime(), DateUtil.date()) && t.getContractExtStatus() != 5 && t.getStatus() == 2).map(t -> t.getElevatorId()).distinct().count();
		projectOverviewVO.setCurMonthRenewalElevatorTotal(curMonthRenewalElevatorTotal);

		// 本月到期项目
		long curMonthExpiryProjectTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractExtStatus(), 1) && (Func.equalsSafe(t.getContractStatus(), 3) || Func.equalsSafe(t.getContractStatus(), 4)) && ((Func.isNotEmpty(t.getContractEndTime()) && DateUtil.isSameMonth(t.getContractEndTime(), DateUtil.date())) || (Func.isNotEmpty(t.getStopTime()) && DateUtil.isSameMonth(t.getStopTime(), DateUtil.date())))).map(BuildingContractPlusVO::getBuildingId).distinct().count();
		projectOverviewVO.setCurMonthExpiryProjectTotal(curMonthExpiryProjectTotal);

		// 本月到期电梯
		long curMonthExpiryElevatorTotal = contractList.stream().filter(t -> Func.equalsSafe(t.getContractExtStatus(), 1) && (Func.equalsSafe(t.getContractStatus(), 3) || Func.equalsSafe(t.getContractStatus(), 4)) && ((Func.isNotEmpty(t.getContractEndTime()) && DateUtil.isSameMonth(t.getContractEndTime(), DateUtil.date())) || (Func.isNotEmpty(t.getStopTime()) && DateUtil.isSameMonth(t.getStopTime(), DateUtil.date())))).map(BuildingContractPlusVO::getElevatorId).distinct().count();
		projectOverviewVO.setCurMonthExpiryElevatorTotal(curMonthExpiryElevatorTotal);

		return projectOverviewVO;
	}

	@Override
	public Integer estateBuildingCountStatistics() {

		Integer estateBuildingCount = baseMapper.estateBuildingCountStatistics();
		return estateBuildingCount;
	}

	@Override
	public List<TlwRankingListVO> rankingList(List<String> deviceList) {
		return baseMapper.rankingList(deviceList);
	}

	@Override
	public List<Building> getListByBuilding(Building building) {
		return baseMapper.getListByBuilding(building);
	}

	@Override
	public Building selectById(Long buildingId) {
		return baseMapper.getById(buildingId);
	}

	@Override
	public Map<String, Object> tlwBuildingElevatorCount(TlwBuildingElevatorQuery tbeQuery) {
		return baseMapper.tlwBuildingElevatorCount(tbeQuery);
	}

	@Override
	public IPage<TlwBuildingVO> selectTlwBuildingElevatorPage(TlwBuildingElevatorQuery tbeQuery, IPage<TlwBuildingVO> page) {
		List<TlwBuildingVO> resultPage = baseMapper.selectTlwBuildingPage(page, tbeQuery);
		if (ObjectUtil.isNotEmpty(resultPage)) {
			List<Long> buildingIds = resultPage.stream().map(TlwBuildingVO::getBuildingId).collect(Collectors.toList());
			tbeQuery.setBuildingIds(buildingIds);
			List<TlwElevatorVO> tlwElevatorVOS = baseMapper.selectTlwElevatorList(tbeQuery);
			resultPage.forEach(e -> {
				List<TlwElevatorVO> elevatorVOS = tlwElevatorVOS.stream().filter(j -> j.getBuildingId().equals(e.getBuildingId())).collect(Collectors.toList());
				e.setElevatorVOS(elevatorVOS);
				if (Func.isNotEmpty(e.getElevatorVOS())) {
					e.getElevatorVOS().forEach(t -> {
						List<Dict> dictList = elevatorService.driverModeFieldSelect("controlMode", t.getDriveModeCode(), null);
						if (Func.isNotEmpty(t.getFieldV())) {
							Dict result = dictList.stream().filter(k -> k.getDictKey().equals(t.getFieldV().getControlMode())).findFirst().orElse(null);
							if (ObjectUtil.isNotEmpty(result)) {
								t.getFieldV().setControlModeName(result.getDictValue());
							}
						}
					});
				}
			});
		}
		return page.setRecords(resultPage);
	}

	@Override
	public List<BuildingVO> selectSearchList(BuildingVO search) {
		List<BuildingVO> list = baseMapper.selectSearchList(search);
		if (Func.isNotEmpty(list)) {
			List<Dict> dictList = DictCache.getList(PROJECT_TYPE_CODE);
			Map<String, String> dictMap = dictList.stream().collect(Collectors.toMap(Dict::getDictKey, Dict::getDictValue));
			for (BuildingVO buildingVO : list) {
				buildingVO.setTypeName(dictMap.get(buildingVO.getType()));
			}
		}

		return list;
	}

	@Override
	public List<TlwBuildingVO> selectTlwBuilding(List<Long> ids) {
		return baseMapper.selectTlwBuilding(ids);
	}

	@Override
	public List<TlwElevatorVO> selectTlwElevator(List<Long> elevatorIds) {
		return baseMapper.selectTlwElevator(elevatorIds);
	}

	@Override
	public List<TlwElevatorEstateUserVO> selectTlwEstateElevatorUser(Long userId) {
		return baseMapper.selectTlwEstateElevatorUser(userId);
	}

	@Override
	public List<BuildingRedisVO> listForVO() {
		return baseMapper.listForRedisVO();
	}

	@Override
	public List<BuildingRescueScreenVO> getRescueScreenB(SugarRescueSearchDTO searchDTO) {
		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId, deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		if (Func.isEmpty(elevatorIds)) {
			return new ArrayList<>();
		}
		return baseMapper.getRescueScreenB(searchDTO.getStartDate(), searchDTO.getEndDate(), elevatorIds);
	}

	@Override
	public List<ElevatorRescueScreenVO> getRescueScreenE(SugarRescueSearchDTO searchDTO) {
		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId, deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		if (Func.isEmpty(elevatorIds)) {
			return new ArrayList<>();
		}
		List<ElevatorRescueScreenVO> result = baseMapper.getRescueScreenE(searchDTO.getStartDate(), searchDTO.getEndDate());
		result = result.stream().filter(e -> elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
		return result.size() > 10 ? result.subList(0, 10) : result;
	}

	@Override
	public List<BuildingRescueScreenVO> getRescueScreenT(SugarRescueSearchDTO searchDTO) {
		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId, deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		if (Func.isEmpty(elevatorIds)) {
			return new ArrayList<>();
		}
		return baseMapper.getRescueScreenT(searchDTO.getStartDate(), searchDTO.getEndDate(), elevatorIds);
	}

	@Override
	public List<UserRescueScreenVO> getRescueScreenU(Date beginTime, Date endTime, Integer sort) {
		List<UserRescueScreenVO> result = baseMapper.getRescueScreenU(beginTime, endTime, sort);
		result.forEach(r -> {
			Long avgArrMiniSeconds = r.getAvgArrMiniSeconds();
			Double d = avgArrMiniSeconds / 60000.0;
			// 保留1位小数
			DecimalFormat decimalFormat = new DecimalFormat("#.#");
			double roundedValue = Double.parseDouble(decimalFormat.format(d));
			r.setAvgArrMinutes(roundedValue);
		});
		return result;
	}

	/**
	 * 2023-10-19 新维修大屏 项目-电梯统计
	 *
	 * @return 结果VO
	 */
	@Override
	public BuildingElevatorCountVO getBuildingElevatorCounts() {
		BuildingElevatorCountVO result = new BuildingElevatorCountVO();
		// 当前租户项目总数
		List<Elevator> mapEleList = elevatorService.getSugarMapEleList();
		final List<Long> buildingIds = mapEleList.stream().map(Elevator::getBuildingId).distinct().collect(Collectors.toList());

		result.setBuildingCount(buildingIds.size());
		// 当前租户电梯总数

		result.setElevatorCount(mapEleList.size());
		// 前 10 项目-电梯数
		List<BuildingPercentageVO> buildingPercentage = baseMapper.buildingPercentage();
		// 当这个列表不为空时，计算
		if (Func.isNotEmpty(buildingPercentage) && result.getBuildingCount() != 0) {
			// 当前协商为 10条， 还会调整
			// 若长度=10, 说明总条数 >= 10,将最后一条变成其它，否则就直接这样计算
			int firstSize = 10;
			if (buildingPercentage.size() == firstSize) {
				// 1. 补充第10条数据 -> 统一变成其它，电梯总数-前9条数据总数，便于区分，id设置为null
				int otherExistCount = 0;
				for (int i = 0; i < buildingPercentage.size() - 1; i++) {
					BuildingPercentageVO buildingPercentageVO = buildingPercentage.get(i);
					otherExistCount += buildingPercentageVO.getBuildingElevatorNum();
				}
				// 获取最后一条数据
				BuildingPercentageVO other = buildingPercentage.get(buildingPercentage.size() - 1);
				other.setBuildingId(null);
				other.setBuildingName("其它");
				other.setBuildingElevatorNum(result.getElevatorCount() - otherExistCount);
				buildingPercentage.set(buildingPercentage.size() - 1, other);
			}
			// 2. 计算电梯占比小数
			BigDecimal elevatorSum = new BigDecimal(result.getElevatorCount());
			for (BuildingPercentageVO eachOne : buildingPercentage) {
				BigDecimal eachElevatorNum = new BigDecimal(eachOne.getBuildingElevatorNum());
				BigDecimal elevatorPercentage = eachElevatorNum.divide(elevatorSum, 5, RoundingMode.HALF_UP);
				eachOne.setElevatorPercentage(elevatorPercentage);
				BigDecimal formatPercentage = elevatorPercentage.multiply(new BigDecimal(100)).setScale(1, RoundingMode.HALF_UP);
				eachOne.setFormatPercentage(formatPercentage + "%");
			}
			result.setBuildingPercentage(buildingPercentage);
		}
		return result;
	}

	@Override
	public SugarMapEleBuildVo getSugarMapEleBuildInfo(SugarSearchDTO searchDTO) {
		SugarMapEleBuildVo sugarMapEleBuildVo = new SugarMapEleBuildVo();

		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId, deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		if (Func.isEmpty(elevatorIds)) {
			return sugarMapEleBuildVo;
		}
		List<Elevator> list = elevatorService.getSugarMapEleList();
		list = list.stream().filter(e -> elevatorIds.contains(e.getId())).collect(Collectors.toList());
		final List<Long> buildingIds = list.stream().map(Elevator::getBuildingId).distinct().collect(Collectors.toList());
		sugarMapEleBuildVo.setBuildingCounts(buildingIds.size());
		sugarMapEleBuildVo.setElevatorCounts(list.size());
		List<Elevator> collect = list.stream().filter(o -> o.getIsStop() == ElevatorStatusEnum.NORMAL.getStatus()).collect(Collectors.toList());
		sugarMapEleBuildVo.setEnElevatorCounts(collect.size());
		sugarMapEleBuildVo.setDisElevatorCounts(sugarMapEleBuildVo.getElevatorCounts() - sugarMapEleBuildVo.getEnElevatorCounts());
		return sugarMapEleBuildVo;
	}


	@Override
	@TenantIgnore
	@Transactional(rollbackFor = Exception.class)
	public boolean stagnationInit() {
		List<BuildingExt> list = buildingExtService.list();
		list.forEach(l -> l.setStagnationPoint(StagnationPointEnum.NOT_LIMIT.getType()));
		return buildingExtService.updateBatchById(list);
	}

	@Override
	public List<BuildingESVO> listForEsInit() {
		return baseMapper.listForEsInit();
	}

	@Override
	@TenantIgnore
	public List<GalaxyMaintainCustomerVO> getGalaxyMaintainCustomerList() {
		return baseMapper.getGalaxyMaintainCustomerList();
	}

	@Override
	public List<SidaBuildingBasicVO> getBuildingListByTenantId(String tenantId) {
		List<SidaBuildingBasicVO> buildingListByTenantId = baseMapper.getBuildingListByTenantId(tenantId);
		// 数据处理：当 allowMaintain = 1 时，需要拼接一个List对象作为保养时段描述
		buildingListByTenantId.forEach(b -> {
			if (new Integer("1").equals(b.getAllowMaintain())) {
				List<SidaBuildingMaintainTimeVO> maintenanceTime = new ArrayList<>();
				List<BuildingMaintainTime> maintenanceTimeSourceList = buildingMaintainTimeService.list(new LambdaQueryWrapper<BuildingMaintainTime>().eq(BuildingMaintainTime::getBuildingId, b.getBuildingId()).eq(BaseEntity::getIsDeleted, 0));
				if (!Func.isEmpty(maintenanceTimeSourceList)) {
					maintenanceTimeSourceList.forEach(mt -> {
						SidaBuildingMaintainTimeVO maintainTimeVO = new SidaBuildingMaintainTimeVO();
						BeanUtils.copyProperties(mt, maintainTimeVO);
						maintenanceTime.add(maintainTimeVO);
					});
				}
				b.setMaintenanceTime(maintenanceTime);
			}
		});
		return buildingListByTenantId;
	}

	@Override
	public List<BiBuildingVO> listBiBuildingList() {
		return baseMapper.listBiBuildingList();
	}

	@Override
	@TenantIgnore
	public List<BuildingMessageVO> selectBuildingMessageList() {
		return baseMapper.selectBuildingMessageList();
	}

	@Override
	public List<BuildingMessageVO> selectBuildingMessageListByBuildingId(Long buildingId) {
		return baseMapper.selectBuildingMessageByBuildingId(buildingId);
	}

	@Override
	@TenantIgnore
	public List<BILarkRescueBigTableVO> getLarkRescueBigTable(Date startDate, Date endDate) {
		return baseMapper.getLarkRescueBigTable(startDate, endDate);
	}

	@Override
	@TenantIgnore
	public List<BILarkRescueBigTableVO> getLarkRescueBigTableByCondition(Date startDate, Date endDate) {
		return baseMapper.getLarkRescueBigTableByCondition(startDate, endDate);
	}

	@Override
	@TenantIgnore
	public List<BILarkGroupSourceVO> getLarkGroupSourceByCondition(Date startDate, Date endDate) {
		return baseMapper.getLarkGroupSourceByCondition(startDate, endDate);
	}

	@Override
	@TenantIgnore
	public List<BILarkRescueBuildingSourceVO> getLarkRescueBuildingSourceByCondition(Date startDate, Date endDate) {
		return baseMapper.getLarkRescueBuildingSourceByCondition(startDate, endDate);
	}

	@Override
	@TenantIgnore
	public List<BILarkRescueAreaResourceVO> getLarkRescueAreaResourceByCondition(Date startDate, Date endDate) {
		return baseMapper.getLarkRescueAreaResourceByCondition(startDate, endDate);
	}

	@Override
	public List<BILarkRescueAreaResourceVO> getLarkRescueAreaPlaceByCondition(Date startDate, Date endDate) {
		return baseMapper.getLarkRescueAreaPlaceByCondition(startDate, endDate);
	}

	@Override
	public List<Building> listByH3Index() {
		return baseMapper.listByH3Index();
	}

	@Override
	public Building getByBuildingNameAndGroup(String buildingName, String groupId) {
		return baseMapper.getByBuildingNameAndGroup(buildingName, groupId);
	}

	@Override
	public List<Long> getBuildingIdsByGroupId(String groupId) {
		return baseMapper.getBuildingIdsByGroupId(groupId);
	}

	@Override
	public BuildingUserStatusVo getBuildingStatus(Long buildingId) {
		BuildingUserStatusVo buildingUserStatusVo = new BuildingUserStatusVo();

		List<MaintainPlanConfig> list = baseMapper.getBuildingStatus(buildingId);

		//计算合作中
		List<MaintainPlanConfig> zbList = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.DIS_ENABLE.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId()).collect(Collectors.toList());
		Integer inTimeBuildingCount = zbList.stream().map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList()).size();
		Integer inTimeElevatorCount = zbList.stream().map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList()).size();
		buildingUserStatusVo.setInTimeBuildingCount(inTimeBuildingCount);
		buildingUserStatusVo.setInTimeElevatorCount(inTimeElevatorCount);

		//处理丢保中
		List<MaintainPlanConfig> dbList = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId()).collect(Collectors.toList());
		buildingUserStatusVo.setDbBuildingCount(dbList.stream().map(MaintainPlanConfig::getBuildingId).distinct().collect(Collectors.toList()).size());
		buildingUserStatusVo.setDbElevatorCount(dbList.stream().map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList()).size());

		//处理潜在
		BuildingUserContractDTO buildingUserContractDTO = new BuildingUserContractDTO();
		buildingUserContractDTO.setType(3);
		List<BuildingUserContract> buildingUserContracts = baseMapper.buildDingListV2(null, buildingUserContractDTO);
		buildingUserStatusVo.setPotentialBuildingCount(buildingUserContracts.size());
		int sum = buildingUserContracts.stream().mapToInt(BuildingUserContract::getElevatorCounts).sum();
		buildingUserStatusVo.setPotentialElevatorCount(sum);


		//全部项目数
		buildingUserStatusVo.setAllBuildingCount(this.count());

		return buildingUserStatusVo;
	}

	@Override
	public IPage<BuildingUserContract> buildDingListV2(BuildingUserContractDTO buildingUserContractDTO) {
		buildingUserContractDTO.setTenantId(AuthUtil.getTenantId());
		Query query = new Query();
		query.setSize(buildingUserContractDTO.getSize());
		query.setCurrent(buildingUserContractDTO.getCurrent());
		IPage<BuildingUserContract> page = Condition.getPage(query);
		List<BuildingUserContract> list = baseMapper.buildDingListV2(buildingUserContractDTO.getSize() != 0 ? page : null, buildingUserContractDTO);
		page.setRecords(list);
		return page;
	}

	@Override
	public BuildingUserElevatorVo elevatorStatus(Long buildingId, Integer timeType) {
		BuildingUserElevatorVo buildingUserElevatorVo = new BuildingUserElevatorVo();
		List<MaintainPlanConfig> list = baseMapper.getBuildingUserStatus(buildingId, timeType);
		for (MaintainPlanConfig config : list) {
			if (config.getMaintainStatus() == null) {
				config.setMaintainStatus(-2);
			}
		}
		//问题梯数
		Integer questionCounts = list.stream().filter(o -> Convert.toInt(o.getIsQuestion(), 0) == 1).collect(Collectors.toList()).size();

		//脱保梯数
		Integer tuoEleCounts = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId()).collect(Collectors.toList()).size();

		//断挡梯数
		Integer gapCounts = list.stream().filter(o -> Convert.toInt(o.getIsGap(), 0) > 0).collect(Collectors.toList()).size();

		//无合同梯数
		Integer noContractCounts = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.DIS_ENABLE.getId()).collect(Collectors.toList()).size();

		//服务电梯数
		Integer inTimeElevatorCount = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.DIS_ENABLE.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END.getId() || o.getMaintainStatus() == ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId()).collect(Collectors.toList()).size();
		Integer abInTimeElevatorCount = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId() && o.getAboutEndDay() <= 90).collect(Collectors.toList()).size();

		//丢保电梯数
		Integer dbElevatorCount = 0;
		if (timeType == 1) {
			dbElevatorCount = baseMapper.getBuildingUserStatus(buildingId, 2).size();
		} else {
			dbElevatorCount = list.stream().filter(o -> o.getMaintainStatus() == ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId()).collect(Collectors.toList()).size();
		}

		buildingUserElevatorVo.setQuestionCounts(questionCounts);
		buildingUserElevatorVo.setTuoEleCounts(tuoEleCounts);
		buildingUserElevatorVo.setGapCounts(gapCounts);
		buildingUserElevatorVo.setNoContractCounts(noContractCounts);
		buildingUserElevatorVo.setInTimeElevatorCount(inTimeElevatorCount);
		buildingUserElevatorVo.setAbInTimeElevatorCount(abInTimeElevatorCount);
		buildingUserElevatorVo.setDbElevatorCount(dbElevatorCount);
		buildingUserElevatorVo.setAllElevatorCount(list.stream().filter(o -> o.getElevatorId() != null).map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList()).size());
		return buildingUserElevatorVo;
	}

	@Override
	public IPage<BuildingUserElevatorDetailVo> elevatorListV2(BuildingUserElevatorDTO buildingUserElevatorDTO) {
		Query query = new Query();
		query.setSize(buildingUserElevatorDTO.getSize());
		query.setCurrent(buildingUserElevatorDTO.getCurrent());
		IPage<BuildingUserElevatorDetailVo> page = Condition.getPage(query);
		List<BuildingUserElevatorDetailVo> list = baseMapper.elevatorListV2(query.getSize() == 0 ? null : page, buildingUserElevatorDTO);
		for (BuildingUserElevatorDetailVo record : list) {
			if (record.getContractId() == null || record.getContractId() == -1) {
				continue;
			}
			if (record.getStatus() == 1) {
				record.setAllStatusDesc("未审核");
			} else if (record.getContractStatus() == 1) {
				record.setAllStatusDesc("未生效");
			} else if (record.getContractStatus() == 2) {
				record.setAllStatusDesc("合同期内");
			} else if (record.getContractStatus() == 3) {
				record.setAllStatusDesc("合同到期");
			} else if (record.getContractStatus() == 4) {
				record.setAllStatusDesc("已终止");
			} else if (record.getContractExtStatus() == 5) {
				record.setAllStatusDesc("已作废");
			} else if (record.getStatus() == 3) {
				record.setAllStatusDesc("审核不通过");
			} else {
				record.setAllStatusDesc("-");
			}
		}
		page.setRecords(list);
		return page;
	}

	/**
	 * 翻译中文到英文
	 *
	 * @param chinese 中文名称
	 * @return 对应的英文名称
	 */
	private String translateToEnglish(String chinese) {
		return TranslationUtil.translateToEnglish(chinese);
	}
}

